/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pr2.cruce;

import java.util.List;
import pr2.cromosoma.CromosomaPVC;

/**
 *
 * @author Gonzalo Ortiz Jaureguizar (gortiz at software.imdea.org)
 */
public class OX extends EstrategiaCruce<CromosomaPVC>{

    int p1, p2;

    public OX(int size) {
        super(size);
    }

    public OX() {
    }

    private void elegirPuntos(int size) {
        p1 = (int) (Math.random() * size);
        p2 = (int) (Math.random() * size);

        if(p1 > p2) {
            int aux = p1;
            p1 = p2;
            p2 = aux;
        }
    }

    private void intercambiar(List<Integer> padre1, List<Integer> padre2, List<Integer> h1, List<Integer> h2) {
        for(int i = p1; i < p2; i++) {
            h1.set(i, padre2.get(i));
            h2.set(i, padre1.get(i));
        }
    }

    @Override
    protected void cruzar(CromosomaPVC padre1, CromosomaPVC padre2, CromosomaPVC hijo1, CromosomaPVC hijo2) {
        elegirPuntos(padre1.getGenes().size());

        int distancia = p2 - p1;
        if(distancia == 1 || distancia == padre1.getGenes().size()) {
            hijo1.copia(padre1);
            hijo2.copia(padre2);
            return ;
        }

        List<Integer> pg1 = padre1.getGenes();
        List<Integer> pg2 = padre2.getGenes();
        List<Integer> hg1 = hijo1.getGenes();
        List<Integer> hg2 = hijo2.getGenes();

        intercambiar(pg1, pg2, hg1, hg2);

        copiarResto(pg1, pg2, hg1, hg2);
    }

    private void copiarResto(List<Integer> pg1, List<Integer> pg2, List<Integer> hg1, List<Integer> hg2) {
        copiarResto(pg1, pg2, hg1);
        copiarResto(pg2, pg1, hg2);
    }

    private void copiarResto(List<Integer> padreActual, List<Integer> otroPadre, List<Integer> hijoActual) {
        final int size = padreActual.size();
        
        int indexPadre = p2;
        int indexHijo = p2;
        while(indexHijo != p1) {
            if(!isEnSubcadena(padreActual, otroPadre, indexPadre)) { //copiamos tal cual
                hijoActual.set(indexHijo, padreActual.get(indexPadre));
                //la siguiente vez escribiremos la posicion del hijo siguiente
                indexHijo = (indexHijo + 1) % size; 
            }
            else { //si esta, buscamos en la posicion siguiente

            }
            indexPadre = (indexPadre + 1) % size; //pasamos a la siguiente posicion
        }

    }

    private boolean isEnSubcadena(List<Integer> padreActual, List<Integer> otroPadre, int indexEnActual) {
        int valor = padreActual.get(indexEnActual);
        for(int i = p1; i < p2; i++) {
            if(otroPadre.get(i) == valor)
                return true;
        }
        return false;
    }

}
